package nonDictionaryTokenAnalyzer;

import inporter.TokenInporter;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import main.tokens;

public class AbbreviationProcessor 
{
	//ArrayList which contains all code file lines (one code file = one line = one array item)
	private ArrayList<String> arlCodeFile;
	
	public AbbreviationProcessor(ArrayList<String> pCodeFile)
	{
		arlCodeFile = pCodeFile;
	}
	
	/*
	 * Function: Search the result for current abbreviation at all location
	 * Input: pTokenWord -> Token with alphabets only
	 * 		  pCntToken -> Current token
	 * Output: strRtn -> Result
	 */
	public String getProcessorResult(String pTokenWord, tokens pCntToken)
	{
		String strRtn = "";
		
		String[] strsLocation;
	    if (pCntToken.getLocation().contains(","))
	    {
	    	strsLocation = pCntToken.getLocation().split(",");
	    }
	    else
	    {
	    	strsLocation = new String[]{pCntToken.getLocation()};
	    }	    
	    
	    //**************************************************************
	    //scan results by scope, multiple
	    String strMultiRtn = "";
	    for (int i = 0; i < strsLocation.length; i++)
	    {
	    	strMultiRtn = strMultiRtn + scanByScopeMulti(pCntToken.getToken(), pTokenWord, strsLocation[i]);
	    }
	    strMultiRtn = removeSameResult(strMultiRtn);
	    //**************************************************************
	    //**************************************************************
	    //scan results in files
	    String strFileRtn = "";
	    strFileRtn = strFileRtn + scanByFiles(pTokenWord);
	    strFileRtn = removeSameResult(strFileRtn);
	    //**************************************************************
	    
	    // Get result from all candidates
	    strRtn = getBestResult(strMultiRtn, strFileRtn + ",");
	    //System.out.println("Result for [" + pCntToken.getToken() + "] is [" + strRtn + "]");
		
		return strRtn;
	}
	
	
	
	/*
	 * Function: Scan tokens between nearest two ";", scan each location where the abbreviation appears
	 * Input: pToken -> Current abbreviation
	 * 		  pTokenWord -> Current abbreviation (alphabets only)
	 * 		  pLoc -> Line number in code file
	 * Output: strRtn -> Analyze result
	 */
	private String scanByScopeMulti(String pToken, String pTokenWord, String pLoc)
	{
		String strRtn = "";
		String strCodeLine = arlCodeFile.get(Integer.parseInt(pLoc.trim()) - 1);
		
		String[] strCodeTokens = strCodeLine.split(" ");
		ArrayList<Integer> arlIndex = new ArrayList<Integer>();
		
		// find the abbreviation's location in current code line
		for (int i = 0; i < strCodeTokens.length; i++)
		{
			if (strCodeTokens[i].equals(pToken))
			{
				arlIndex.add(i);
			}
		}
		
		// get sub string by searching the nearest ";"
		for (int i = 0; i < arlIndex.size(); i++)
		{
			int intFront = arlIndex.get(i);
			int intRear = intFront;
			while (!strCodeTokens[intFront].contains(";") && intFront >= -1)
			{
				intFront --;
			}		
			while (!strCodeTokens[intRear].contains(";") && intRear <= strCodeTokens.length)
			{
				intRear ++;
			}
			// strCnt -> sub string
			String strCnt = "";	
			for (int j = intFront + 1; j <= intRear; j++)
			{
				strCnt = strCnt + strCodeTokens[j] + " ";
			}
			//System.out.println(strCnt);
			strRtn = strRtn + AbbCombi(pTokenWord, strCnt);
		}
		
		//*******************************************************
					
		//System.out.println();
		//System.out.println("[" + strCnt + "] Searching for [" + pToken + "]");
		//System.out.println("Result for token [" + pToken + "] is [" + strRtn + "]");
		
		//*******************************************************
		
		return strRtn;
	}
	
	/*
	 * Function: Scan tokens from files
	 * Input: pTokenWord -> Current abbreviation (alphabets only)
	 * Output: strRtn -> Analyze result
	 */
	private String scanByFiles(String pTokenWord)
	{
		String strRtn = "";
		
		TokenInporter clsTInporter = new TokenInporter();
		ArrayList<String> arlFileLines = clsTInporter.arlGetFileLines("input\\source.txt");
		
		for (int i = 0; i < arlFileLines.size(); i++)
		{
			strRtn = strRtn + AbbCombi(pTokenWord, arlFileLines.get(i));
		}

		return strRtn;
	}
	
	/*
	 * Function: Match abbreviation by using regular expression (Combination)
	 * Input: pTokenWord -> Current abbreviation (alphabets only)
	 * 		  pCnt -> Current Code Line (Sub string)
	 * Output: strResult -> Analyze result
	 */
	private String AbbCombi(String pTokenWord, String pCnt)
	{
		String strRtn = "";
		char[] charAbb = pTokenWord.toCharArray();
		
		String s = "";
		for (int i = 0; i < charAbb.length; i++)
		{
			s =  s + charAbb[i] + "[a-z]*[ ]*";
		}
        Pattern  pattern=Pattern.compile(s);
        Matcher  ma=pattern.matcher(pCnt.toLowerCase());
        while (ma.find())
        {
        	if (!strRtn.contains(ma.group().trim() + ", "))
        	{
        		strRtn = strRtn + ma.group().trim() + ", ";
        	}
        }
        
        // get rid of the result which is as same as pTokenWord
        String strResult = "";
        if (strRtn.contains(pTokenWord + ", "))
        {
        	strResult = strRtn.substring(0, strRtn.indexOf(pTokenWord + ", "));
        	strResult = strResult + strRtn.substring((strRtn.indexOf(pTokenWord + ", ") + pTokenWord.length() + 2));
        }
        else
        {
        	strResult = strRtn;
        }
		
		return strResult;
		
	}
	
	/*
	 * Function: Remove the same result from current result
	 * Input: pRtn -> Current result before process
	 * Output: strRtn -> result after process
	 */
	private String removeSameResult(String pRtn)
	{
		String strRtn = "";
		
		if (pRtn.contains(", "))
		{
			String[] strsBefore = pRtn.split(", ");
			ArrayList<String> arlAfter = new ArrayList<String>();
			
			for (int i = 0; i < strsBefore.length; i ++)
			{
				if (!strsBefore[i].trim().equals("") && !arlAfter.contains(strsBefore[i].trim()))
				{
					arlAfter.add(strsBefore[i].trim());
				}
			}
			
			for (int i = 0; i < arlAfter.size(); i ++)
			{
				strRtn = strRtn + arlAfter.get(i) + ", ";
			}
			strRtn = strRtn.substring(0, strRtn.length() - 2);
		}
		else
		{
			strRtn = pRtn;
		}
		
		return strRtn;
	}
	
	/*
	 * Function: Get the best result for current abbreviation from all candidates
	 * Input: pMultiRtn -> all candidates from code
	 * 		  pFileRtn -> all candidates from file
	 * Output: strRtn -> result(s)
	 */
	private String getBestResult(String pMultiRtn, String pFileRtn)
	{
		String strRtn = "";
		String[] strMultiRtns;
		
		if (!pMultiRtn.equals("") && !pMultiRtn.contains(","))
		{
			strMultiRtns = new String[] {pMultiRtn};
		}
		else
		{
			strMultiRtns  = pMultiRtn.split(",");
		}
		
		for (int i = 0; i < strMultiRtns.length; i++)
		{
			//System.out.println(strMultiRtns[i].trim() + ", ");
			if (pFileRtn.contains(strMultiRtns[i].trim() + ", "))
			{
				strRtn = strRtn + strMultiRtns[i].trim() + ", ";
			}
		}
		
		if (!strRtn.equals(""))
		{
			strRtn = strRtn.substring(0 , strRtn.length() - 2);
		}
		
		return strRtn;
	}
	
}
